package com.colin.library.help;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.text.TextUtils;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by Colin on 2017/2/14.
 */
public class BitmapHelp {


    //内部类Holder只有在getInstance()方法第一次调用的时候才会被加载（实现了lazy），而且其加载过程是线程安全的（实现线程安全）。
    // 内部类加载的时候实例化一次instance。
    public static class Holder {
        static BitmapHelp instance = new BitmapHelp();
    }

    private BitmapHelp() {
    }

    public static BitmapHelp getInstance() {
        return Holder.instance;
    }

    /**
     * 判断图片文件是否需要旋转 需要旋转正常
     *
     * @param file
     * @return
     */
    public File getRotateImageFromCamera(File file) {
        int degree = getImageDegree(file);
        //旋转处理
        //File 转 Bitmap
        Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
        if (null == bitmap) {
            return file;
        }
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
            LogHelp.e(e.getMessage());
        }
        //Bitmap 转 File
        if (null != bitmap) {
            try {
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bufferedOutputStream);
                bufferedOutputStream.flush();
                bufferedOutputStream.close();
            } catch (IOException e) {
                LogHelp.e(e.getMessage());
            }
        }
        if (null != bitmap) {
            bitmap.recycle();
            bitmap = null;
        }
        return file;
    }

    /**
     * 处理图片  压缩
     *
     * @param imageFile    源图片文件
     * @param newImageFile 压缩图片文件
     * @return newImageFile
     */
    public File getNewImageFile(File imageFile, File newImageFile) {
        if (null == imageFile || null == newImageFile) {
            LogHelp.e("两个文件夹其中一个为空");
            return null;
        }
        //File 转 Bitmap 压缩图片 保存新图片
        Bitmap bitmap = getImage(imageFile.getAbsolutePath());
        if (null == bitmap) {
            LogHelp.e("图片压缩错误");
            return null;
        }
        //Bitmap 转 File
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(newImageFile.getAbsolutePath())));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            LogHelp.e("bitmap转file错误");
            LogHelp.e(e.getMessage());
        }
        //垃圾回收
        if (null != bitmap && !bitmap.isRecycled()) {
            bitmap.recycle();
            bitmap = null;
        }
        return newImageFile;
    }

    /**
     * 图片按比例大小压缩方法
     *
     * @param srcPath （根据路径获取图片并压缩）
     * @return
     */
    public static Bitmap getImage(String srcPath) {
        if (TextUtils.isEmpty(srcPath)) {
            LogHelp.e("路径错误");
            return null;
        }
        BitmapFactory.Options options = new BitmapFactory.Options();
        // 开始读入图片，此时把options.inJustDecodeBounds 设回true了
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, options);// 此时返回bitmap为空
        int w = options.outWidth;
        int h = options.outHeight;
        // 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        float hh = 800f;// 这里设置高度为800f
        float ww = 480f;// 这里设置宽度为480f
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (options.outWidth / ww);
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (options.outHeight / hh);
        }
        if (be <= 0) {
            be = 1;
        }
        options.inSampleSize = be;// 设置缩放比例
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(srcPath, options);
        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
    }

    /**
     * 质量压缩方法
     *
     * @param bitmap
     * @return
     */
    public static Bitmap compressImage(Bitmap bitmap) {
        if (null == bitmap) {
            return null;
        }
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 90;

        while (byteArrayOutputStream.toByteArray().length / 1024 > 400) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            byteArrayOutputStream.reset(); // 重置baos即清空baos
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, byteArrayOutputStream);// 这里压缩options%，把压缩后的数据存放到baos中
            options -= 5;// 每次都减少10
        }
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        return BitmapFactory.decodeStream(byteArrayInputStream, null, null);// 把ByteArrayInputStream数据生成图片
    }

    /**
     * 读取图片属性：旋转的角度
     *
     * @param file 图片文件
     * @return degree旋转的角度
     */
    public int getImageDegree(File file) {
        int degree = 0;
        if (null == file) {
            return degree;
        }
        ExifInterface exifInterface = null;
        try {
            exifInterface = new ExifInterface(file.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (null == exifInterface) {
            return degree;
        }
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                degree = 90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                degree = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                degree = 270;
                break;
        }
        return degree;
    }

    /**
     * 判断图片文件是否需要旋转 需要旋转正常
     *
     * @param file 图片文件
     * @return degree旋转的角度
     */
    public File rotateBitmapFile(File file, int degree) {
        if (null == file) {
            return file;
        }
        if (degree == 0) {
            return file;
        }
        //旋转处理

        //File 转 Bitmap
        Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
            LogHelp.e(e.getMessage());
        }
        //Bitmap 转 File
        if (null != bitmap) {
            try {
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                bos.flush();
                bos.close();
            } catch (IOException e) {
                LogHelp.e(e.getMessage());
            }
        }
        return file;
    }

    /**
     * 图片旋转操作
     *
     * @param bitmap 需要旋转的图片
     * @param degree 旋转角度
     * @return 旋转后的图片
     */
    private Bitmap rotateBitmap(Bitmap bitmap, int degree) {
        Bitmap rotateBitmap = null;
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {
            rotateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
            LogHelp.e(e.getMessage());
        }
        if (rotateBitmap == null) {
            rotateBitmap = bitmap;
        }
        if (bitmap != rotateBitmap) {
            bitmap.recycle();
        }
        return rotateBitmap;
    }
}
